'''
Created on Apr 23, 2012

@author: root
'''
from Base import Base
from Disk import Disk
from FileOps import FileOps
from Filesystem import Filesystem
from Module import Module
from Node import Node
from Project import Project
from Role import Role
from Software2 import Software2
from User import User
from XML_File import XML_File
from NodeInfo import NodeInfo
import Queue
import csv
import datetime
import os
import tarfile
import threading
import time

class LZOCompression(Base):

    
    binName = ""
    binDir = ""
    binPath = ""
    projectName = "hadoop"
    sw =""
    Nodes = []
    Users = []
    clusterName = ""
    project = None
    remoteProjectDir = "/tmp/pachyderm/hadoop"
    goldDir = "./conf/config_files/gold/hadoop"
    backupDir = "./conf/config_files/previous/hadoop"
    configDir = "./conf/config_files"
    installConfigDir = "/usr/lib/gphd/hadoop/conf"
    fileops = None
    nodeInfo = None

          
    def BuildProject(self,Nodes):
     
        ''' Define the Project and Add Appropriate Roles '''
        self.LogInfo("Building HDFS LZO Compression Project for Installation")
        print "    * Build HDFS LZO Compression Project for Installation"
     
        modCnt = 0
        
        if (float((Nodes[0].osVersion).split()[0]) -5 < 1):
            projectConfig = "./conf/project/hdfs-lzo-compression-el5.def"
            print "        * RedHat 5.X Detected"
            self.LogInfo("Red Hat 5.x Detected. Using "+projectConfig)

        elif (float((Nodes[0].osVersion).split()[0]) -5 >= 1):
            projectConfig = "./conf/project/hdfs-lzo-compression-el6.def"
            print "        * RedHat 6.X Detected"
            self.LogInfo("Red Hat 6.x Detected. Using "+projectConfig)
        
        
               
            
        self.project = Project(self.projectName,"version",self.binPath)
        self.project.AddRole(Role("LZOCompression","*"))
        for role in self.project.Roles:
            self.LogInfo("Role Added:"+role.name)      
        
        self.LogInfo("Reading HDFS LZO Compression Project Definition File")
        
        try: 
            for row in csv.DictReader(open(projectConfig), 'personality installorder rpm'.split()):
                if (len(row) == 3):
                    personality = row['personality']
                    installOrder = int(row['installorder'])
                    rpm = row['rpm']
                    self.LogInfo(projectConfig+":"+str(row))
                else:
                    self.LogError("Incorrect Number of Parameters in HDFS LZO Compression Project Definition File.")
                    print "    * ERROR: Incorrect Number of Parameters in HDFS LZO Compression Project Definition File."
                                  
                for role in self.project.Roles:
                    if (str(personality) == str(role.personality)):
                        for fileName in Software2.swFilenames:
                            if (str(rpm) in str(fileName)):
                                role.AddModule(Module(fileName,True,installOrder))
                                self.LogInfo("Add Module: "+str(fileName))
                                modCnt += 1
                                
    
                                
            self.LogInfo("Completed Reading HDFS LZO Compression Project Definition File")
        except Exception, err:
            self.LogError("Problem Loading HDFS LZO Compression Project Definition File")
            return -1
     
     
     
     
     
    
    def CheckConfig(self,Nodes,Users):
        nodeSTR = ""
        nodeCnt = 0
        cfgStatus =0
        for node in Nodes:
            nodeCnt +=1
            if (nodeCnt%6 == 0):
                eoLine = "\n"
            else:
                eoLine = ""
            nodeSTR += (","+node.hostName+eoLine)
        nodeSTR=nodeSTR[1:]
      
        self.LogInfo("Installation Verification Report")
        self.LogInfo("-----------------------------------------")
        self.LogInfo("Project:         "+str(self.projectName))
        self.LogInfo("Node(s):     "+str(nodeSTR))
       
        print "---------------------------------------------------"
        print "           INSTALLATION VERIFICATION REPORT    "
        print "---------------------------------------------------"
        print "* Project:         "+str(self.projectName)
        print "* Node(s):     "+str(nodeSTR)
      
        if (cfgStatus == 0 ):
            print "---------------------------------------------------"
            choice = self.query_yes_no("Is this Configuration Correct?","yes")
            print "---------------------------------------------------"
            if choice:
                return 0
            else:
                return -1
        else:
            time.sleep(4)
            return -1
    
    def LoadNodes(self,configPath):
        self.LogInfo("Loading Node Configuration File @"+ str(configPath))
        try: 
            for row in csv.DictReader(open(configPath), 'hostname ipaddress'.split()):
                if (len(row) == 2):

                    hostname = row['hostname'] 
                    ipAddress = row['ipaddress']  
                    personalities = "*" 
                    node = Node(hostname,ipAddress,personalities)
                    self.Nodes.append(node)
                    self.LogInfo(row)
                else:
                    self.LogError("Incorrect Number of Parameters in Node Config File.")

                    return -1
            self.LogInfo("Configuration File Loaded")
            return 0   
        except Exception, err:
            self.LogError("Problem Loading Node Configuration File")
            return -1
    
        
   
    def PushConfig(self,Nodes,Users):
            status = 0
            print "    * Push Modified Versions of Hadoop Configuration Files to Entire Cluster"
            self.LogInfo("Push Modified Versions of Hadoop Configuration Files to Entire Cluster")
            status += self.fileops.Push(Nodes,Users,self.goldDir+"/"+"core-site.xml",self.installConfigDir+"/core-site.xml")
            status += self.fileops.Push(Nodes,Users,self.goldDir+"/"+"mapred-site.xml",self.installConfigDir+"/mapred-site.xml")

            if (status ==  0):
                print "    * Completed Push of Modified Versions of Hadoop Configuration Files to Entire Cluster"
                self.LogInfo("Completed Push of Modified Versions of Hadoop Configuration Files to Entire Cluster")
            else:
                print "    * ERROR: Could Not Push Modified Versions of all Hadoop Configuration Files to Entire Cluster"
                self.LogError("Could Not Push Modified Versions of all Hadoop Configuration Files to Entire Cluster")
            return status
        

    def ModifyConfig(self):
        
        choice = self.query_yes_no("Would you like to enable Map Output Compression as well?","yes")
        fileName = "core-site.xml"
        print "---------------------------------------------------"
        print "---------------------------------------------------"
        xmlFile = XML_File(self.configDir,fileName)
        prevFile = str(fileName+"."+datetime.datetime.now().strftime("%Y%m%d-%H:%M"))

        #Backup
        print "    * Saving Prior Version of "+fileName+" to "+self.configDir+"/previous/hadoop/"+prevFile
        self.LogInfo("Saving Prior Version of "+fileName+" to "+self.configDir+"/previous/hadoop/"+prevFile)
        self.fileops.LocalPush(self.configDir+"/gold/hadoop/"+fileName,self.configDir+"/previous/hadoop/"+prevFile)

        
        print "    * Making Modifications to the Gold Copy of "+fileName
        
        
            
        (found,valueSTR) = xmlFile.GetValue("io.compression.codecs")
        if (not found):     
            nvArray=[]
            try:                

                rdr = csv.DictReader(open(str(self.goldDir)+"/lzo-compression.core.properties","r"), delimiter=";", fieldnames=('name','value'))
                for row in rdr:
                    nvPair={}
                    nvPair['name']=row['name']
                    nvPair['value']=row['value']
                    nvArray.append(nvPair)
            except Exception, err:
                self.LogError("Problem Loading HDFS LZO Compression Additional Properties File"+str(err))
                return -1
            
            
            coresite = open(str(self.goldDir)+"/"+fileName,"r")
            coresiteLines = coresite.readlines()
            coresite.close()
            coresite = open(str(self.goldDir)+"/"+fileName,"w")
            for line in coresiteLines:
                if ("</configuration>" not in str(line) ):
                    coresite.writelines(line)
            coresite.close()
            xmlFile.AddProperty(nvArray)
            coresite = open(str(self.goldDir)+"/"+fileName,"a")
            coresite.write("</configuration>\n")
            coresite.close()
        else:
            print "        * "+fileName+" already included Compression Values"


        if (choice):
            fileName = "mapred-site.xml"
            xmlFile = XML_File(self.configDir,fileName)
            prevFile = str(fileName+"."+datetime.datetime.now().strftime("%Y%m%d-%H:%M"))
    
            #Backup
            print "    * Saving Prior Version of "+fileName+" to "+self.configDir+"/previous/hadoop/"+prevFile
            self.LogInfo("Saving Prior Version of "+fileName+" to "+self.configDir+"/previous/hadoop/"+prevFile)
            self.fileops.LocalPush(self.configDir+"/gold/hadoop/"+fileName,self.configDir+"/previous/hadoop/"+prevFile)
    
            
            print "    * Making Modifications to the Gold Copy of "+fileName
            
            
                
            (found,valueSTR) = xmlFile.GetValue("mapred.map.output.compression.codec")
            if (not found):     
                nvArray=[]
                try:                
    
                    rdr = csv.DictReader(open(str(self.goldDir)+"/lzo-compression.mapred.properties","r"), delimiter=";", fieldnames=('name','value'))
                    for row in rdr:
                        nvPair={}
                        nvPair['name']=row['name']
                        nvPair['value']=row['value']
                        nvArray.append(nvPair)
                except Exception, err:
                    self.LogError("Problem Loading HDFS LZO Compression Additional Properties File"+str(err))
                    return -1
                
                
                coresite = open(str(self.goldDir)+"/"+fileName,"r")
                coresiteLines = coresite.readlines()
                coresite.close()
                coresite = open(str(self.goldDir)+"/"+fileName,"w")
                for line in coresiteLines:
                    if ("</configuration>" not in str(line) ):
                        coresite.writelines(line)
                coresite.close()
                xmlFile.AddProperty(nvArray)
                coresite = open(str(self.goldDir)+"/"+fileName,"a")
                coresite.write("</configuration>\n")
                coresite.close()
            else:
                print "        * "+fileName+" already included Compression Values"






       # elif (str(fileName).uppper() == "MAPRED-SITE.XML"):   
        
 



     
    def __init__(self,binPath,clusterName,projectName):
        Base.__init__(self)
        self.binPath = binPath
        
        ''' Take the entry from the -g entry and parse the components '''
        
        binComponents = self.binPath[1:].split('/')
        self.binName = binComponents[len(binComponents)-1]
        binComponents.remove(self.binName)
        for comp in (binComponents):
            self.binDir = self.binDir + "/" + comp
        print "    * Starting HDFS LZO Compression Software Install on Cluster: " + clusterName
        self.LogInfo("Starting HDFS LZO Compression Software Install on Cluster: " + clusterName)
        self.fileops = FileOps()
        self.projectName = projectName
        
#        self.binDir = binDir
#        self.binName = binName

        